package com.tianbao54.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Scanner;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

/**
 * @author ZHANGYUPENG
 */
public class NioClient {

    private static SocketChannel socketChannel = null;
    private static final ByteBuffer sendBuffer = ByteBuffer.allocate(1024);

    private void init () {

        Executor executor = Executors.newSingleThreadExecutor(Executors.defaultThreadFactory());
        executor.execute(new ClientHandler());
        try (Scanner scanner = new Scanner(System.in)) {
            while (scanner.hasNextLine()) {
                String line = scanner.nextLine();
                NioServer.sendMessageToChannel(socketChannel,sendBuffer,line);
            }
        }
    }

    public static void main(String[] args) {
        new NioClient().init();
    }

    private static String receiveFromChannel (SocketChannel socketChannel,ByteBuffer buffer) {

        try {
            buffer.clear();
            int count = socketChannel.read(buffer);
            if (count > 0 ) {
                return new String (buffer.array(),0,count);
            } else if (count == 0) {
                return null;
            } else {
                socketChannel.close();
                return null;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private static class ClientHandler implements Runnable {

        private static final ByteBuffer receiveBuffer = ByteBuffer.allocate(1024);

        @Override
        public void run() {

            try (SocketChannel socketChannel = SocketChannel.open();
                 Selector selector = Selector.open()) {

                socketChannel.configureBlocking(false);
                socketChannel.connect(new InetSocketAddress("9.181.61.40",8888));
                socketChannel.register(selector, SelectionKey.OP_CONNECT);

                for (;;) {

                    if (selector.select() <= 0)
                        continue;
                    for (Iterator<SelectionKey> iterator = selector.selectedKeys().iterator(); iterator.hasNext();) {
                        SelectionKey key = iterator.next();
                        iterator.remove();
                        if (key.isConnectable()) {

                            if (socketChannel.isConnectionPending())
                                socketChannel.finishConnect();
                            NioClient.socketChannel = socketChannel;
                            socketChannel.register(selector,SelectionKey.OP_READ);
                        }
                        if (key.isReadable()) {

                            String message = receiveFromChannel(socketChannel,receiveBuffer);
                            System.out.println(message);
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}